<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Authorization Architecture :: Spring Security</title>
<link rel="canonical" href="../../../servlet/authorization/architecture.html">
<link rel="prev" href="index.html">
<link rel="next" href="authorize-requests.html">
<meta name="generator" content="Antora 3.0.0">
<link rel="stylesheet" href="../../../_/css/site.css">
<link href="../../../_/img/favicon.ico" rel='shortcut icon' type='image/vnd.microsoft.icon'>
<link rel="stylesheet" href="../../../_/css/vendor/docsearch.min.css">

<script>var uiRootPath = '../../../_'</script>
</head>
<body class="article">
<header class="header">
<nav class="navbar">
<div class="navbar-brand">
<a class="navbar-item" href="https://spring.io">
<img id="springlogo" class="block" src="../../../_/img/spring-logo.svg" alt="Spring">
</a>
<button class="navbar-burger" data-target="topbar-nav">
<span></span>
<span></span>
<span></span>
</button>
</div>
<div id="topbar-nav" class="navbar-menu">
<div class="navbar-end">
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="architecture.html#">Why Spring</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="https://spring.io/why-spring">Overview</a>
<a class="navbar-item" href="https://spring.io/microservices">Microservices</a>
<a class="navbar-item" href="https://spring.io/reactive">Reactive</a>
<a class="navbar-item" href="https://spring.io/event-driven">Event Driven</a>
<a class="navbar-item" href="https://spring.io/cloud">Cloud</a>
<a class="navbar-item" href="https://spring.io/web-applications">Web Applications</a>
<a class="navbar-item" href="https://spring.io/serverless">Serverless</a>
<a class="navbar-item" href="https://spring.io/batch">Batch</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="architecture.html#">Learn</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="https://spring.io/learn">Overview</a>
<a class="navbar-item" href="https://spring.io/quickstart">Quickstart</a>
<a class="navbar-item" href="https://spring.io/guides">Guides</a>
<a class="navbar-item" href="https://spring.io/blog">Blog</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="architecture.html#">Projects</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="https://spring.io/projects">Overview</a>
<a class="navbar-item" href="https://spring.io/projects/spring-boot">Spring Boot</a>
<a class="navbar-item" href="https://spring.io/projects/spring-framework">Spring Framework</a>
<a class="navbar-item" href="https://spring.io/projects/spring-cloud">Spring Cloud</a>
<a class="navbar-item" href="https://spring.io/projects/spring-cloud-dataflow">Spring Cloud Data Flow</a>
<a class="navbar-item" href="https://spring.io/projects/spring-data">Spring Data</a>
<a class="navbar-item" href="https://spring.io/projects/spring-integration">Spring Integration</a>
<a class="navbar-item" href="https://spring.io/projects/spring-batch">Spring Batch</a>
<a class="navbar-item" href="https://spring.io/projects/spring-security">Spring Security</a>
<a class="navbar-item navbar-item-special" href="https://spring.io/projects">View all projects</a>
<a class="navbar-item" href="https://spring.io/tools">Spring Tools 4</a>
<a class="navbar-item navbar-item-special-2" href="https://start.spring.io">Spring Initializr <svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><polyline points="15 10.94 15 15 1 15 1 1 5.06 1" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="2"></polyline><polyline points="8.93 1 15 1 15 7.07" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="2"></polyline><line x1="15" y1="1" x2="8" y2="8" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="2"></line></svg></a>
</div>
</div>
<a class="navbar-item" href="https://spring.io/training">Training</a>
<a class="navbar-item" href="https://spring.io/support">Support</a>
<div class="navbar-item has-dropdown is-hoverable is-community">
<a class="navbar-link" href="architecture.html#">Community</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="https://spring.io/community">Overview</a>
<a class="navbar-item" href="https://spring.io/events">Events</a>
<a class="navbar-item" href="https://spring.io/team">Team</a>
</div>
</div>
</div>
</div>
<div id="switch-theme">
<input type="checkbox" id="switch-theme-checkbox" />
<label for="switch-theme-checkbox">Dark Theme</label>
</div>
</nav>
</header>
<div class="body">
<div class="nav-container" data-component="ROOT" data-version="5.6.0-RC1">
<aside class="nav">
<div class="panels">
<div class="nav-panel-menu is-active" data-panel="menu">
<nav class="nav-menu">
<h3 class="title"><a href="../../index.html">Spring Security</a></h3>
<ul class="nav-list">
<li class="nav-item" data-depth="0">
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../index.html">Overview</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../prerequisites.html">Prerequisites</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../community.html">Community</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../whats-new.html">What&#8217;s New</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../getting-spring-security.html">Getting Spring Security</a>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../features/index.html">Features</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../features/authentication/index.html">Authentication</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../features/authentication/password-storage.html">Password Storage</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../features/exploits/index.html">Protection Against Exploits</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../features/exploits/csrf.html">CSRF</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../features/exploits/headers.html">HTTP Headers</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../features/exploits/http.html">HTTP Requests</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../features/integrations/index.html">Integrations</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../features/integrations/cryptography.html">Cryptography</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../features/integrations/data.html">Spring Data</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../features/integrations/concurrency.html">Java&#8217;s Concurrency APIs</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../features/integrations/jackson.html">Jackson</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../features/integrations/localization.html">Localization</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../modules.html">Project Modules</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../samples.html">Samples</a>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../index.html">Servlet Applications</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../getting-started.html">Getting Started</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../architecture.html">Architecture</a>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../authentication/index.html">Authentication</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../authentication/architecture.html">Authentication Architecture</a>
</li>
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../authentication/passwords/index.html">Username/Password</a>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<button class="nav-item-toggle"></button>
<span class="nav-text">Reading Username/Password</span>
<ul class="nav-list">
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../authentication/passwords/form.html">Form</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../authentication/passwords/basic.html">Basic</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../authentication/passwords/digest.html">Digest</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="4">
<button class="nav-item-toggle"></button>
<span class="nav-text">Password Storage</span>
<ul class="nav-list">
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../authentication/passwords/in-memory.html">In Memory</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../authentication/passwords/jdbc.html">JDBC</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../authentication/passwords/user-details.html">UserDetails</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../authentication/passwords/user-details-service.html">UserDetailsService</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../authentication/passwords/password-encoder.html">PasswordEncoder</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../authentication/passwords/dao-authentication-provider.html">DaoAuthenticationProvider</a>
</li>
<li class="nav-item" data-depth="5">
<a class="nav-link" href="../authentication/passwords/ldap.html">LDAP</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../authentication/session-management.html">Session Management</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../authentication/rememberme.html">Remember Me</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../authentication/openid.html">OpenID</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../authentication/anonymous.html">Anonymous</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../authentication/preauth.html">Pre-Authentication</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../authentication/jaas.html">JAAS</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../authentication/cas.html">CAS</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../authentication/x509.html">X509</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../authentication/runas.html">Run-As</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../authentication/logout.html">Logout</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../authentication/events.html">Authentication Events</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="index.html">Authorization</a>
<ul class="nav-list">
<li class="nav-item is-current-page" data-depth="3">
<a class="nav-link" href="architecture.html">Authorization Architecture</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="authorize-requests.html">Authorize HTTP Requests</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="expression-based.html">Expression-Based Access Control</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="secure-objects.html">Secure Object Implementations</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="method-security.html">Method Security</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="acls.html">Domain Object Security ACLs</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../oauth2/index.html">OAuth2</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../oauth2/oauth2-login.html">OAuth2 Log In</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../oauth2/oauth2-client.html">OAuth2 Client</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../oauth2/oauth2-resourceserver.html">OAuth2 Resource Server</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../saml2/index.html">SAML2</a>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../exploits/index.html">Protection Against Exploits</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../exploits/csrf.html">Cross Site Request Forgery (CSRF) for Servlet Environments</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../exploits/headers.html">Security HTTP Response Headers</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../exploits/http.html">HTTP</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../exploits/firewall.html">HttpFirewall</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../integrations/index.html">Integrations</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../integrations/servlet-api.html">Servlet APIs</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../integrations/mvc.html">Spring MVC</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../integrations/websocket.html">WebSocket</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../integrations/cors.html">Spring&#8217;s CORS Support</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../integrations/jsp-taglibs.html">JSP Taglib</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<span class="nav-text">Configuration</span>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../configuration/java.html">Java Configuration</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../configuration/kotlin.html">Kotlin Configuration</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../configuration/xml-namespace.html">Namespace Configuration</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../test/index.html">Testing</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../test/method.html">Method Security</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../test/mockmvc.html">MockMvc Support</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../appendix/index.html">Appendix</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../appendix/database-schema.html">Database Schemas</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../appendix/namespace.html">XML Namespace</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../appendix/faq.html">FAQ</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../reactive/index.html">Reactive Applications</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../reactive/getting-started.html">Getting Started</a>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<span class="nav-text">Authentication</span>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/authentication/x509.html">X.509 Authentication</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/authentication/logout.html">Logout</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<span class="nav-text">Authorization</span>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/authorization/method.html">EnableReactiveMethodSecurity</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../reactive/oauth2/index.html">OAuth2</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/oauth2/login.html">OAuth 2.0 Login</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/oauth2/oauth2-client.html">OAuth2 Client</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/oauth2/resource-server.html">OAuth 2.0 Resource Server</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/registered-oauth2-authorized-client.html">@RegisteredOAuth2AuthorizedClient</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../reactive/exploits/index.html">Protection Against Exploits</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/exploits/csrf.html">CSRF</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/exploits/headers.html">Headers</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/exploits/http.html">HTTP Requests</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<span class="nav-text">Integrations</span>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/integrations/cors.html">CORS</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/integrations/rsocket.html">RSocket</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../reactive/integrations/webclient.html">WebClient</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../reactive/test.html">Testing</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../reactive/configuration/webflux.html">WebFlux Security</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</div>
<div class="nav-panel-explore" data-panel="explore">
<div class="context">
<span class="title">Spring Security</span>
<span class="version">5.6.0-RC1</span>
</div>
<ul class="components">
<li class="component is-current">
<a class="title" href="../../../index.html">Spring Security</a>
<ul class="versions">
<li class="version">
<a href="../../../6.0/index.html">6.0.0-SNAPSHOT</a>
</li>
<li class="version">
<a href="../../../6.0.0-M3/index.html">6.0.0-M3</a>
</li>
<li class="version">
<a href="../../../6.0.0-M2/index.html">6.0.0-M2</a>
</li>
<li class="version">
<a href="../../../6.0.0-M1/index.html">6.0.0-M1</a>
</li>
<li class="version">
<a href="../../../5.7/index.html">5.7.0-SNAPSHOT</a>
</li>
<li class="version">
<a href="../../../5.7.0-RC1/index.html">5.7.0-RC1</a>
</li>
<li class="version">
<a href="../../../5.7.0-M3/index.html">5.7.0-M3</a>
</li>
<li class="version">
<a href="../../../5.7.0-M2/index.html">5.7.0-M2</a>
</li>
<li class="version">
<a href="../../../5.7.0-M1/index.html">5.7.0-M1</a>
</li>
<li class="version">
<a href="../../../5.6.4/index.html">5.6.4-SNAPSHOT</a>
</li>
<li class="version is-latest">
<a href="../../../index.html">5.6.3</a>
</li>
<li class="version">
<a href="../../../5.6.2/index.html">5.6.2</a>
</li>
<li class="version">
<a href="../../../5.6.1/index.html">5.6.1</a>
</li>
<li class="version">
<a href="../../../5.6.0/index.html">5.6.0</a>
</li>
<li class="version is-current">
<a href="../../index.html">5.6.0-RC1</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</aside>
</div>
<main class="article">
<div class="toolbar" role="navigation">
<button class="nav-toggle"></button>
<nav class="breadcrumbs" aria-label="breadcrumbs">
<ul>
<li><a href="../../index.html">Spring Security</a></li>
<li><a href="../index.html">Servlet Applications</a></li>
<li><a href="index.html">Authorization</a></li>
<li><a href="architecture.html">Authorization Architecture</a></li>
</ul>
</nav>
<div class="search">
<input id="search-input" type="text" placeholder="Search docs">
</div>
<div class="page-versions">
<button class="version-menu-toggle" title="Show other versions of page">5.6.0-RC1</button>
<div class="version-menu">
<a class="version" href="../../../6.0/servlet/authorization/architecture.html">6.0.0-SNAPSHOT</a>
<a class="version" href="../../../6.0.0-M3/servlet/authorization/architecture.html">6.0.0-M3</a>
<a class="version" href="../../../6.0.0-M2/servlet/authorization/architecture.html">6.0.0-M2</a>
<a class="version" href="../../../6.0.0-M1/servlet/authorization/architecture.html">6.0.0-M1</a>
<a class="version" href="../../../5.7/servlet/authorization/architecture.html">5.7.0-SNAPSHOT</a>
<a class="version" href="../../../5.7.0-RC1/servlet/authorization/architecture.html">5.7.0-RC1</a>
<a class="version" href="../../../5.7.0-M3/servlet/authorization/architecture.html">5.7.0-M3</a>
<a class="version" href="../../../5.7.0-M2/servlet/authorization/architecture.html">5.7.0-M2</a>
<a class="version" href="../../../5.7.0-M1/servlet/authorization/architecture.html">5.7.0-M1</a>
<a class="version" href="../../../5.6.4/servlet/authorization/architecture.html">5.6.4-SNAPSHOT</a>
<a class="version" href="../../../servlet/authorization/architecture.html">5.6.3</a>
<a class="version" href="../../../5.6.2/servlet/authorization/architecture.html">5.6.2</a>
<a class="version" href="../../../5.6.1/servlet/authorization/architecture.html">5.6.1</a>
<a class="version" href="../../../5.6.0/servlet/authorization/architecture.html">5.6.0</a>
<a class="version is-current" href="architecture.html">5.6.0-RC1</a>
</div>
</div>
<div class="edit-this-page"><a href="https://github.com/spring-projects/spring-security/blob/5.6.0-RC1/docs/modules/ROOT/pages/servlet/authorization/architecture.adoc">Edit this Page</a></div>
</div>
<div class="content">
<aside class="toc sidebar" data-title="Contents" data-levels="2">
<div class="toc-menu"></div>
</aside>
<article class="doc">
<div class="admonitionblock important">
<table>
<tbody><tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p> For the latest stable version, please use <a href="../../../servlet/authorization/architecture.html">Spring Security 5.6.3</a>!</p>
</div>
</td>
</tr></tbody>
</table>
</div>
<h1 id="page-title" class="page">Authorization Architecture</h1>
<div class="sect1">
<h2 id="authz-authorities"><a class="anchor" href="architecture.html#authz-authorities"></a>Authorities</h2>
<div class="sectionbody">
<div class="paragraph">
<p><a href="../authentication/architecture.html#servlet-authentication-authentication" class="xref page"><code>Authentication</code></a>, discusses how all <code>Authentication</code> implementations store a list of <code>GrantedAuthority</code> objects.
These represent the authorities that have been granted to the principal.
The <code>GrantedAuthority</code> objects are inserted into the <code>Authentication</code> object by the <code>AuthenticationManager</code> and are later read by <code>AccessDecisionManager</code>s when making authorization decisions.</p>
</div>
<div class="paragraph">
<p><code>GrantedAuthority</code> is an interface with only one method:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">String getAuthority();</code></pre>
</div>
</div>
<div class="paragraph">
<p>This method allows
<code>AccessDecisionManager</code>s to obtain a precise <code>String</code> representation of the <code>GrantedAuthority</code>.
By returning a representation as a <code>String</code>, a <code>GrantedAuthority</code> can be easily "read" by most <code>AccessDecisionManager</code>s.
If a <code>GrantedAuthority</code> cannot be precisely represented as a <code>String</code>, the <code>GrantedAuthority</code> is considered "complex" and <code>getAuthority()</code> must return <code>null</code>.</p>
</div>
<div class="paragraph">
<p>An example of a "complex" <code>GrantedAuthority</code> would be an implementation that stores a list of operations and authority thresholds that apply to different customer account numbers.
Representing this complex <code>GrantedAuthority</code> as a <code>String</code> would be quite difficult, and as a result the <code>getAuthority()</code> method should return <code>null</code>.
This will indicate to any <code>AccessDecisionManager</code> that it will need to specifically support the <code>GrantedAuthority</code> implementation in order to understand its contents.</p>
</div>
<div class="paragraph">
<p>Spring Security includes one concrete <code>GrantedAuthority</code> implementation, <code>SimpleGrantedAuthority</code>.
This allows any user-specified <code>String</code> to be converted into a <code>GrantedAuthority</code>.
All <code>AuthenticationProvider</code>s included with the security architecture use <code>SimpleGrantedAuthority</code> to populate the <code>Authentication</code> object.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="authz-pre-invocation"><a class="anchor" href="architecture.html#authz-pre-invocation"></a>Pre-Invocation Handling</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Spring Security provides interceptors which control access to secure objects such as method invocations or web requests.
A pre-invocation decision on whether the invocation is allowed to proceed is made by the <code>AccessDecisionManager</code>.</p>
</div>
<div class="sect2">
<h3 id="authz-access-decision-manager"><a class="anchor" href="architecture.html#authz-access-decision-manager"></a>The AccessDecisionManager</h3>
<div class="paragraph">
<p>The <code>AccessDecisionManager</code> is called by the <code>AbstractSecurityInterceptor</code> and is responsible for making final access control decisions.
The <code>AccessDecisionManager</code> interface contains three methods:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">void decide(Authentication authentication, Object secureObject,
	Collection&lt;ConfigAttribute&gt; attrs) throws AccessDeniedException;

boolean supports(ConfigAttribute attribute);

boolean supports(Class clazz);</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>AccessDecisionManager</code>'s <code>decide</code> method is passed all the relevant information it needs in order to make an authorization decision.
In particular, passing the secure <code>Object</code> enables those arguments contained in the actual secure object invocation to be inspected.
For example, let&#8217;s assume the secure object was a <code>MethodInvocation</code>.
It would be easy to query the <code>MethodInvocation</code> for any <code>Customer</code> argument, and then implement some sort of security logic in the <code>AccessDecisionManager</code> to ensure the principal is permitted to operate on that customer.
Implementations are expected to throw an <code>AccessDeniedException</code> if access is denied.</p>
</div>
<div class="paragraph">
<p>The <code>supports(ConfigAttribute)</code> method is called by the <code>AbstractSecurityInterceptor</code> at startup time to determine if the <code>AccessDecisionManager</code> can process the passed <code>ConfigAttribute</code>.
The <code>supports(Class)</code> method is called by a security interceptor implementation to ensure the configured <code>AccessDecisionManager</code> supports the type of secure object that the security interceptor will present.</p>
</div>
</div>
<div class="sect2">
<h3 id="authz-voting-based"><a class="anchor" href="architecture.html#authz-voting-based"></a>Voting-Based AccessDecisionManager Implementations</h3>
<div class="paragraph">
<p>Whilst users can implement their own <code>AccessDecisionManager</code> to control all aspects of authorization, Spring Security includes several <code>AccessDecisionManager</code> implementations that are based on voting.
<a href="architecture.html#authz-access-voting">Voting Decision Manager</a> illustrates the relevant classes.</p>
</div>
<div id="authz-access-voting" class="imageblock">
<div class="content">
<img src="../../_images/servlet/authorization/access-decision-voting.png" alt="access decision voting">
</div>
<div class="title">Figure 1. Voting Decision Manager</div>
</div>
<div class="paragraph">
<p>Using this approach, a series of <code>AccessDecisionVoter</code> implementations are polled on an authorization decision.
The <code>AccessDecisionManager</code> then decides whether or not to throw an <code>AccessDeniedException</code> based on its assessment of the votes.</p>
</div>
<div class="paragraph">
<p>The <code>AccessDecisionVoter</code> interface has three methods:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">int vote(Authentication authentication, Object object, Collection&lt;ConfigAttribute&gt; attrs);

boolean supports(ConfigAttribute attribute);

boolean supports(Class clazz);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Concrete implementations return an <code>int</code>, with possible values being reflected in the <code>AccessDecisionVoter</code> static fields <code>ACCESS_ABSTAIN</code>, <code>ACCESS_DENIED</code> and <code>ACCESS_GRANTED</code>.
A voting implementation will return <code>ACCESS_ABSTAIN</code> if it has no opinion on an authorization decision.
If it does have an opinion, it must return either <code>ACCESS_DENIED</code> or <code>ACCESS_GRANTED</code>.</p>
</div>
<div class="paragraph">
<p>There are three concrete <code>AccessDecisionManager</code>s provided with Spring Security that tally the votes.
The <code>ConsensusBased</code> implementation will grant or deny access based on the consensus of non-abstain votes.
Properties are provided to control behavior in the event of an equality of votes or if all votes are abstain.
The <code>AffirmativeBased</code> implementation will grant access if one or more <code>ACCESS_GRANTED</code> votes were received (i.e. a deny vote will be ignored, provided there was at least one grant vote).
Like the <code>ConsensusBased</code> implementation, there is a parameter that controls the behavior if all voters abstain.
The <code>UnanimousBased</code> provider expects unanimous <code>ACCESS_GRANTED</code> votes in order to grant access, ignoring abstains.
It will deny access if there is any <code>ACCESS_DENIED</code> vote.
Like the other implementations, there is a parameter that controls the behaviour if all voters abstain.</p>
</div>
<div class="paragraph">
<p>It is possible to implement a custom <code>AccessDecisionManager</code> that tallies votes differently.
For example, votes from a particular <code>AccessDecisionVoter</code> might receive additional weighting, whilst a deny vote from a particular voter may have a veto effect.</p>
</div>
<div class="sect3">
<h4 id="authz-role-voter"><a class="anchor" href="architecture.html#authz-role-voter"></a>RoleVoter</h4>
<div class="paragraph">
<p>The most commonly used <code>AccessDecisionVoter</code> provided with Spring Security is the simple <code>RoleVoter</code>, which treats configuration attributes as simple role names and votes to grant access if the user has been assigned that role.</p>
</div>
<div class="paragraph">
<p>It will vote if any <code>ConfigAttribute</code> begins with the prefix <code>ROLE_</code>.
It will vote to grant access if there is a <code>GrantedAuthority</code> which returns a <code>String</code> representation (via the <code>getAuthority()</code> method) exactly equal to one or more <code>ConfigAttributes</code> starting with the prefix <code>ROLE_</code>.
If there is no exact match of any <code>ConfigAttribute</code> starting with <code>ROLE_</code>, the <code>RoleVoter</code> will vote to deny access.
If no <code>ConfigAttribute</code> begins with <code>ROLE_</code>, the voter will abstain.</p>
</div>
</div>
<div class="sect3">
<h4 id="authz-authenticated-voter"><a class="anchor" href="architecture.html#authz-authenticated-voter"></a>AuthenticatedVoter</h4>
<div class="paragraph">
<p>Another voter which we&#8217;ve implicitly seen is the <code>AuthenticatedVoter</code>, which can be used to differentiate between anonymous, fully-authenticated and remember-me authenticated users.
Many sites allow certain limited access under remember-me authentication, but require a user to confirm their identity by logging in for full access.</p>
</div>
<div class="paragraph">
<p>When we&#8217;ve used the attribute <code>IS_AUTHENTICATED_ANONYMOUSLY</code> to grant anonymous access, this attribute was being processed by the <code>AuthenticatedVoter</code>.
See the Javadoc for this class for more information.</p>
</div>
</div>
<div class="sect3">
<h4 id="authz-custom-voter"><a class="anchor" href="architecture.html#authz-custom-voter"></a>Custom Voters</h4>
<div class="paragraph">
<p>Obviously, you can also implement a custom <code>AccessDecisionVoter</code> and you can put just about any access-control logic you want in it.
It might be specific to your application (business-logic related) or it might implement some security administration logic.
For example, you&#8217;ll find a <a href="https://spring.io/blog/2009/01/03/spring-security-customization-part-2-adjusting-secured-session-in-real-time">blog article</a> on the Spring web site which describes how to use a voter to deny access in real-time to users whose accounts have been suspended.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="authz-after-invocation-handling"><a class="anchor" href="architecture.html#authz-after-invocation-handling"></a>After Invocation Handling</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Whilst the <code>AccessDecisionManager</code> is called by the <code>AbstractSecurityInterceptor</code> before proceeding with the secure object invocation, some applications need a way of modifying the object actually returned by the secure object invocation.
Whilst you could easily implement your own AOP concern to achieve this, Spring Security provides a convenient hook that has several concrete implementations that integrate with its ACL capabilities.</p>
</div>
<div class="paragraph">
<p><a href="architecture.html#authz-after-invocation">After Invocation Implementation</a> illustrates Spring Security&#8217;s <code>AfterInvocationManager</code> and its concrete implementations.</p>
</div>
<div id="authz-after-invocation" class="imageblock">
<div class="content">
<img src="../../_images/servlet/authorization/after-invocation.png" alt="after invocation">
</div>
<div class="title">Figure 2. After Invocation Implementation</div>
</div>
<div class="paragraph">
<p>Like many other parts of Spring Security, <code>AfterInvocationManager</code> has a single concrete implementation, <code>AfterInvocationProviderManager</code>, which polls a list of <code>AfterInvocationProvider</code>s.
Each <code>AfterInvocationProvider</code> is allowed to modify the return object or throw an <code>AccessDeniedException</code>.
Indeed multiple providers can modify the object, as the result of the previous provider is passed to the next in the list.</p>
</div>
<div class="paragraph">
<p>Please be aware that if you&#8217;re using <code>AfterInvocationManager</code>, you will still need configuration attributes that allow the <code>MethodSecurityInterceptor</code>'s <code>AccessDecisionManager</code> to allow an operation.
If you&#8217;re using the typical Spring Security included <code>AccessDecisionManager</code> implementations, having no configuration attributes defined for a particular secure method invocation will cause each <code>AccessDecisionVoter</code> to abstain from voting.
In turn, if the <code>AccessDecisionManager</code> property &#8220;allowIfAllAbstainDecisions&#8221; is <code>false</code>, an <code>AccessDeniedException</code> will be thrown.
You may avoid this potential issue by either (i) setting &#8220;allowIfAllAbstainDecisions&#8221; to <code>true</code> (although this is generally not recommended) or (ii) simply ensure that there is at least one configuration attribute that an <code>AccessDecisionVoter</code> will vote to grant access for.
This latter (recommended) approach is usually achieved through a <code>ROLE_USER</code> or <code>ROLE_AUTHENTICATED</code> configuration attribute.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="authz-hierarchical-roles"><a class="anchor" href="architecture.html#authz-hierarchical-roles"></a>Hierarchical Roles</h2>
<div class="sectionbody">
<div class="paragraph">
<p>It is a common requirement that a particular role in an application should automatically "include" other roles.
For example, in an application which has the concept of an "admin" and a "user" role, you may want an admin to be able to do everything a normal user can.
To achieve this, you can either make sure that all admin users are also assigned the "user" role.
Alternatively, you can modify every access constraint which requires the "user" role to also include the "admin" role.
This can get quite complicated if you have a lot of different roles in your application.</p>
</div>
<div class="paragraph">
<p>The use of a role-hierarchy allows you to configure which roles (or authorities) should include others.
An extended version of Spring Security&#8217;s <a href="architecture.html#authz-role-voter">RoleVoter</a>, <code>RoleHierarchyVoter</code>, is configured with a <code>RoleHierarchy</code>, from which it obtains all the "reachable authorities" which the user is assigned.
A typical configuration might look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml">&lt;bean id="roleVoter" class="org.springframework.security.access.vote.RoleHierarchyVoter"&gt;
	&lt;constructor-arg ref="roleHierarchy" /&gt;
&lt;/bean&gt;
&lt;bean id="roleHierarchy"
		class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl"&gt;
	&lt;property name="hierarchy"&gt;
		&lt;value&gt;
			ROLE_ADMIN &gt; ROLE_STAFF
			ROLE_STAFF &gt; ROLE_USER
			ROLE_USER &gt; ROLE_GUEST
		&lt;/value&gt;
	&lt;/property&gt;
&lt;/bean&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here we have four roles in a hierarchy <code>ROLE_ADMIN &#8658; ROLE_STAFF &#8658; ROLE_USER &#8658; ROLE_GUEST</code>.
A user who is authenticated with <code>ROLE_ADMIN</code>, will behave as if they have all four roles when security constraints are evaluated against an <code>AccessDecisionManager</code> configured with the above <code>RoleHierarchyVoter</code>.
The <code>&gt;</code> symbol can be thought of as meaning "includes".</p>
</div>
<div class="paragraph">
<p>Role hierarchies offer a convenient means of simplifying the access-control configuration data for your application and/or reducing the number of authorities which you need to assign to a user.
For more complex requirements you may wish to define a logical mapping between the specific access-rights your application requires and the roles that are assigned to users, translating between the two when loading the user information.</p>
</div>
</div>
</div>
<nav class="pagination">
<span class="prev"><a href="index.html">Authorization</a></span>
<span class="next"><a href="authorize-requests.html">Authorize HTTP Requests</a></span>
</nav>
</article>
</div>
</main>
</div>
<footer class="footer flex">
<div id="spring-links flex">
<img id="springlogo" src="../../../_/img/spring-logo.svg" alt="Spring">
<p class="smallest antialiased">© <script>var d = new Date();
        document.write(d.getFullYear());</script> <a href="https://www.vmware.com/">VMware</a>, Inc. or its affiliates. <a href="https://www.vmware.com/help/legal.html">Terms of Use</a> • <a href="https://www.vmware.com/help/privacy.html" rel="noopener noreferrer">Privacy</a> • <a href="https://spring.io/trademarks">Trademark Guidelines</a> <span id="thank-you-mobile">• <a href="https://spring.io/thank-you">Thank you</a></span> • <a href="https://www.vmware.com/help/privacy/california-privacy-rights.html">Your California Privacy Rights</a> • <a class="ot-sdk-show-settings">Cookie Settings</a> <span id="teconsent"></span></p>
<p class="smallest antialiased">Apache®, Apache Tomcat®, Apache Kafka®, Apache Cassandra&trade;, and Apache Geode&trade; are trademarks or registered trademarks of the Apache Software Foundation in the United States and/or other countries. Java&trade;, Java&trade; SE, Java&trade; EE, and OpenJDK&trade; are trademarks of Oracle and/or its affiliates. Kubernetes® is a registered trademark of the Linux Foundation in the United States and other countries. Linux® is the registered trademark of Linus Torvalds in the United States and other countries. Windows® and Microsoft® Azure are registered trademarks of Microsoft Corporation. “AWS” and “Amazon Web Services” are trademarks or registered trademarks of Amazon.com Inc. or its affiliates. All other trademarks and copyrights are property of their respective owners and are only mentioned for informative purposes. Other names may be trademarks of their respective owners.</p>
</div>
<div id="social-icons" class="flex jc-between">
<a href="https://www.youtube.com/user/SpringSourceDev" title="Youtube"><svg id="youtube-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><circle class="cls-1" cx="20" cy="20" r="20" /><path class="cls-2" d="M30.91,14.53a2.89,2.89,0,0,0-2-2C27.12,12,20,12,20,12s-7.12,0-8.9.47a2.9,2.9,0,0,0-2,2A30.56,30.56,0,0,0,8.63,20a30.44,30.44,0,0,0,.46,5.47,2.89,2.89,0,0,0,2,2C12.9,28,20,28,20,28s7.12,0,8.9-.47a2.87,2.87,0,0,0,2-2A30.56,30.56,0,0,0,31.37,20,28.88,28.88,0,0,0,30.91,14.53ZM17.73,23.41V16.59L23.65,20Z" /></svg></a>
<a href="https://github.com/spring-projects" title="Github"><svg id="github-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 75.93 75.93"><path class="cls-1" d="M38,0a38,38,0,1,0,38,38A38,38,0,0,0,38,0Z" /></g><path class="cls-2" d="M38,15.59A22.95,22.95,0,0,0,30.71,60.3c1.15.21,1.57-.5,1.57-1.11s0-2,0-3.9c-6.38,1.39-7.73-3.07-7.73-3.07A6.09,6.09,0,0,0,22,48.86c-2.09-1.42.15-1.39.15-1.39a4.81,4.81,0,0,1,3.52,2.36c2,3.5,5.37,2.49,6.67,1.91a4.87,4.87,0,0,1,1.46-3.07c-5.09-.58-10.45-2.55-10.45-11.34a8.84,8.84,0,0,1,2.36-6.15,8.29,8.29,0,0,1,.23-6.07s1.92-.62,6.3,2.35a21.82,21.82,0,0,1,11.49,0c4.38-3,6.3-2.35,6.3-2.35a8.29,8.29,0,0,1,.23,6.07,8.84,8.84,0,0,1,2.36,6.15c0,8.81-5.37,10.75-10.48,11.32a5.46,5.46,0,0,1,1.56,4.25c0,3.07,0,5.54,0,6.29s.42,1.33,1.58,1.1A22.94,22.94,0,0,0,38,15.59Z" /></svg></a>
<a href="https://twitter.com/springcentral" title="Twitter"><svg id="twitter-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 75.93 75.93"><circle class="cls-1" cx="37.97" cy="37.97" r="37.97" /><path id="Twitter-2" data-name="Twitter" class="cls-2" d="M55.2,22.73a15.43,15.43,0,0,1-4.88,1.91,7.56,7.56,0,0,0-5.61-2.49A7.78,7.78,0,0,0,37,30a7.56,7.56,0,0,0,.2,1.79,21.63,21.63,0,0,1-15.84-8.23,8,8,0,0,0,2.37,10.52,7.66,7.66,0,0,1-3.48-1v.09A7.84,7.84,0,0,0,26.45,41a7.54,7.54,0,0,1-2,.28A7.64,7.64,0,0,1,23,41.09a7.71,7.71,0,0,0,7.18,5.47,15.21,15.21,0,0,1-9.55,3.37,15.78,15.78,0,0,1-1.83-.11,21.41,21.41,0,0,0,11.78,3.54c14.13,0,21.86-12,21.86-22.42,0-.34,0-.68,0-1a15.67,15.67,0,0,0,3.83-4.08,14.9,14.9,0,0,1-4.41,1.24A7.8,7.8,0,0,0,55.2,22.73Z" /></svg></a>
</div>
</footer>
<script src="../../../_/js/site.js"></script>
<script async src="../../../_/js/vendor/highlight.js"></script>
<script async src="../../../_/js/vendor/tabs.js"></script>
<script src="../../../_/js/vendor/switchtheme.js"></script>
<script src="../../../_/js/vendor/docsearch.min.js"></script>

<script>
var search = docsearch({
  appId: '244V8V9FGG',
  apiKey: '82c7ead946afbac3cf98c32446154691',
  indexName: 'security-docs',
  inputSelector: '#search-input',
  autocompleteOptions: { hint: false, keyboardShortcuts: ['s'] },
  algoliaOptions: { hitsPerPage: 10 }
}).autocomplete
search.on('autocomplete:closed', function () { search.autocomplete.setVal() })
</script>
<script>if (window.parent == window) {(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create', 'UA-2728886-23', 'auto', {'siteSpeedSampleRate': 100});ga('send', 'pageview');}</script><script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"702d4201299797ee","token":"bffcb8a918ae4755926f76178bfbd26b","version":"2021.12.0","si":100}' crossorigin="anonymous"></script>
</body>
</html>
